package com.guaoran.interview.spring.aop.config;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author : 孤傲然
 * @description : AspectJ
 * @date :2020/1/2 15:53
 */
//@Component
//声明这是一个切面Bean，AnnotaionAspect是一个面，由框架实现的
@Aspect
public class AnnotationAspectJ {

    //配置切入点,该方法无方法体,主要为方便同类中其他方法使用此处配置的切入点
    //切点的集合，这个表达式所描述的是一个虚拟面（规则）
    //就是为了Annotation扫描时能够拿到注解中的内容
    @Pointcut("execution(public * com.guaoran.interview.spring.aop.service.AopService.* (..))")
    public void pointcut(){}
    /*
     * 配置前置通知,使用在方法pointcut()上注册的切入点
     * 同时接受JoinPoint切入点对象,可以没有该参数
     */
    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        System.out.println("before ... joinPoint:"+joinPoint);
    }

    //配置环绕通知,使用在方法aspect()上注册的切入点
    @Around("pointcut()")
    public void around(JoinPoint joinPoint){
        long start = System.currentTimeMillis();
        try {
            ((ProceedingJoinPoint) joinPoint).proceed();
            long end = System.currentTimeMillis();
            System.out.println(("around " + joinPoint + "\tUse time : " + (end - start) + " ms!"));
        } catch (Throwable e) {
            long end = System.currentTimeMillis();
            System.out.println(("around " + joinPoint + "\tUse time : " + (end - start) + " ms with exception : " + e.getMessage()));
        }
    }


    //配置后置返回通知,使用在方法pointcut()上注册的切入点
    @AfterReturning("pointcut()")
    public void afterReturning(JoinPoint joinPoint){
        System.out.println("afterReturning ... joinPoint:"+joinPoint);
    }
    //配置抛出异常后通知,使用在方法pointcut()上注册的切入点
    @AfterThrowing(pointcut = "pointcut()",throwing = "ex")
    public void  afterThrowing(JoinPoint joinPoint, Exception ex){
        System.out.println("afterThrowing ... joinPoint:"+joinPoint +"\n ex:"+ex.toString());
    }

    // 配置后置通知,使用在方法pointcut()上注册的切入点
    @After(value = "pointcut()")
    public void after(JoinPoint joinPoint){
        System.out.println("after ... joinPoint:"+joinPoint);
    }
}
